package com.news.service;

import com.news.config.Constant;
import com.news.dao.ChannelDao;
import com.news.dao.ColumnDao;
import com.news.exception.BusinessError;
import com.news.exception.BusinessException;
import com.news.model.ChannelEntity;
import com.news.model.ColumnEntity;
import com.news.util.URLGenerator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by lingzhiyuan.
 * Date : 15/10/8.
 * Time : 下午9:11.
 * Description:
 */

@Service
@Transactional
public class ChannelService {

    @Resource
    private ChannelDao channelDao;
    @Resource
    private ColumnDao columnDao;

    /**
     * 获取所有频道
     *  包括栏目
     * */
    public List<ChannelEntity> listChannelsAndColumns(){

        List<ChannelEntity> channels;
        channels = channelDao.listChannels();
        this.getColumnsByChannels(channels);
        return channels;
    }

    /**
     * 获取所有的频道
     *  不包括栏目
     *  */
    public List<ChannelEntity> listAllChannels(){
        List<ChannelEntity> channels;
        channels = channelDao.listChannels();
        return channels;
    }

    /**
     * 获取所有频道对应的栏目
     *  注意：不区分状态
     *  */
    private void getColumnsByChannels(List<ChannelEntity> channels){

        List<ColumnEntity> allColumns = new ArrayList<>();
        List<ColumnEntity> tempColumns;
        Set channelIdSet = new HashSet<>();

        // 若List为空则跳过不执行查询操作
        if (channels != null){
            for (ChannelEntity channel : channels){
                channelIdSet.add(channel.getChannel_id());
            }

            if (channelIdSet != null && channelIdSet.size() != 0){
                allColumns = columnDao.findColumnsByChannelIds(channelIdSet);
            }

        }

        // 遍历获得的栏目集合，存入对应频道中
        if (allColumns != null && allColumns.size() != 0) {
            for (ChannelEntity channel : channels){
                long channel_id = channel.getChannel_id();
                Iterator iterator = allColumns.iterator();
                tempColumns = new ArrayList<>();
                while (iterator.hasNext()){

                    ColumnEntity column = (ColumnEntity)iterator.next();
                    if (column.getChannel_id() == channel_id){
                        tempColumns.add(column);
                        iterator.remove();
                    }

                }
                channel.setColumns(tempColumns);
            }
        }
    }


    /**
     * 根据频道主键ID获得频道对象
     * 包括栏目
     * */
    public ChannelEntity getChannelAndColumnsByChannelId(long channel_id) {

        ChannelEntity channel = channelDao.getById(ChannelEntity.class,channel_id);
        if (channel != null){
            List<ColumnEntity> columns = columnDao.findColumnsByChannelId(channel_id);
            if (columns != null){
                channel.setColumns(columns);
            }
        }else {
            throw new BusinessException(BusinessError.ERROR_CHANNEL_NOT_FOUND);
        }
        return channel;
    }

    /**
     * 新增一个频道
     *      URL随机生成，以ch开头
     *      创建时间为当前服务器时间
     *      初始状态为下线状态
     *      顺序为最末尾
     *      */
    public ChannelEntity saveNewChannel(String title,int type){
        ChannelEntity channel = new ChannelEntity();
        int sequence = 1;


        String url = URLGenerator.generate("/ch");
        channel = new ChannelEntity();
        channel.setStatus(Constant.CHANNEL_COLUMN_ARTICLE_STATUS_DISACTIVE);
        ChannelEntity lastChannel = channelDao.getLastChannelInSequence();
        if (lastChannel != null){
            sequence = lastChannel.getSequence()+1;
        }

        channel.setTitle(title);
        channel.setType(type);
        channel.setUrl(url);
        channel.setSequence(sequence);

        channelDao.saveOrUpdate(channel);
        return channel;
    }

    /**
     * 更新频道
     * 这里只更新名称和类型，状态单独更新
     *  @param channel_id   需要更新的频道id
     *  @param title        新的频道名称
     *  @param type         新的频道类型
     *
     *      */
    public ChannelEntity updateChannel(long channel_id, String title, int type) {
        ChannelEntity channel;

        channel = channelDao.getById(ChannelEntity.class,channel_id);

        channel.setTitle(title);
        channel.setType(type);

        channelDao.saveOrUpdate(channel);
        return channel;
    }

    /**
     * 删除特定的一个频道
     *  同时删除对应的所有栏目
     *  */
    public void deleteChannel(long channel_id){
        ChannelEntity channel = columnDao.getById(ChannelEntity.class, channel_id);
        if (channel != null){
            Set ids = new HashSet<>();
            ids.add(channel_id);
            List columns = columnDao.findColumnsByChannelIds(ids);
            channelDao.delete(channel);
            columnDao.batchDelete(columns);
        }else {
            throw new BusinessException(BusinessError.ERROR_COLUMN_NOT_FOUND);
        }
    }

    /**
     * 更改频道的状态
     *  如果当前为在线，则更改为离线
     *  如果当前为离线，则更改为在线
     *      返回一个message
     *  */
    public String updateChannelStatus(long channel_id) {

        String message = "";
        ChannelEntity channel = channelDao.getById(ChannelEntity.class,channel_id);
        if (channel == null){
            throw new BusinessException(BusinessError.ERROR_CHANNEL_NOT_FOUND);
        }
        Integer status = channel.getStatus();
        switch (status){
            case Constant.CHANNEL_COLUMN_ARTICLE_STATUS_ACTIVE:
                channel.setStatus(Constant.CHANNEL_COLUMN_ARTICLE_STATUS_DISACTIVE);
                message = "下线成功";
                break;
            case Constant.CHANNEL_COLUMN_ARTICLE_STATUS_DISACTIVE:
                channel.setStatus(Constant.CHANNEL_COLUMN_ARTICLE_STATUS_ACTIVE);
                message = "上线成功";
                break;
            default:
                throw new BusinessException(BusinessError.ERROR_STATUS_NOT_FOUND);
        }
        channelDao.saveOrUpdate(channel);
        return message;
    }

    /**
     * 更新所有频道的顺序
     *  根据所有频道的id在集合中的顺序重新排序
     *  */
    public void updateChannelSequence(List<Long> ids) {
        List<ChannelEntity> channels = channelDao.listChannels();
        int index = 0;

        if (channels != null && channels.size() != 0){
            for (long channel_id : ids){
                Iterator<ChannelEntity> iterator  = channels.iterator();
                while (iterator.hasNext()){
                    ChannelEntity channel = iterator.next();
                    if (channel.getChannel_id() == channel_id){
                        channel.setSequence(++index);
                        iterator.remove();
                    }
                }
            }

            channelDao.batchSaveOrUpdate(channels);
        }
    }
}
